﻿using System.Collections.Generic;
using System.Linq;
using RimWorld;
using Verse;
using Verse.AI;
using Verse.AI.Group;


namespace ARMIR
{
    public class HediffComp_marchInFormation : HediffComp
    {
        public HediffCompProperties_marchInFormation Props => (HediffCompProperties_marchInFormation)props;
        private int gapTryGiveJob;
        private int hasJobGap; //拥有工作的间隔
        private int gapGiveUp; //间隔放弃
        private int gapMelee; //近战任务间隔
        private List<IntVec3> listPosition; //六个目标位置偏移
        private bool firstLeaveBlade; //首次离开边缘
        public override void CompPostMake()
        {
            base.CompPostMake();
            gapTryGiveJob = 0;
            hasJobGap = 0;
            gapGiveUp = 0;
            firstLeaveBlade = false;
            //bossMoveDetect = new IntVec3();
            listPosition = new List<IntVec3>();
            listPosition.Add(new IntVec3(-1,0,2));
            listPosition.Add(new IntVec3(1,0,2));
            listPosition.Add(new IntVec3(-2,0,0));
            listPosition.Add(new IntVec3(2,0,0));
            listPosition.Add(new IntVec3(-1,0,-2));
            listPosition.Add(new IntVec3(1,0,-2));
        }
        public override void CompExposeData()
        {
            base.CompExposeData();
            Scribe_Collections.Look(ref listPosition, "listPosition", LookMode.Value);
            Scribe_Values.Look(ref firstLeaveBlade, "首次离开边缘", false);
            // 确保列表在加载时不为null
            if (Scribe.mode == LoadSaveMode.LoadingVars && listPosition == null)
            {
                listPosition = new List<IntVec3>();
                // 如果加载失败，重新初始化位置列表
                if (listPosition.Count == 0)
                {
                    listPosition.Add(new IntVec3(-1, 0, 2));
                    listPosition.Add(new IntVec3(1, 0, 2));
                    listPosition.Add(new IntVec3(-2, 0, 0));
                    listPosition.Add(new IntVec3(2, 0, 0));
                    listPosition.Add(new IntVec3(-1, 0, -2));
                    listPosition.Add(new IntVec3(1, 0, -2));
                }
            }
        }
        public override void CompPostTick(ref float severityAdjustment)
        {
            base.CompPostTick(ref severityAdjustment);
            //if (parent.pawn == null) {
            //    parent.pawn.health.RemoveHediff(parent);
            //}
            if (parent.pawn.Downed || parent.pawn.Dead) { //如果盾卫死亡或倒地
                parent.pawn.health.RemoveHediff(parent); //清理寻路
            }
            if (hasJobGap > 0) { 
                hasJobGap--;
            }
            if (gapGiveUp > 0)
            {
                gapGiveUp--;
            }
            if (gapMelee > 0) { 
                gapMelee--;
            }
            gapTryGiveJob++;
            if (gapTryGiveJob > 5) { //每一段tick修正盾卫的行为工作
                moveToRosmontisAround();
                leaveCheck();
                gapTryGiveJob = 0;
            }
        }
        private void moveToRosmontisAround() { 
            //检查地图上是否存在Rosmontis，以其hediff源石脑干为标记
            List<Pawn> Rosmontis = new List<Pawn>();
            Rosmontis = parent.pawn.Map.mapPawns.AllHumanlikeSpawned.Where
            (p => p.health.hediffSet.HasHediff(DefDatabase<HediffDef>.GetNamed("ARMIR_OriginiumBrainStem")) && p.Faction == parent.pawn.Faction
            && !p.Downed
            && !p.Dead).ToList();
            if (Rosmontis.Count >= 1) { //地图上存在boss迷迭香
                //检查迷迭香的移动状态
                //bool bossMoved = false;
                //if (Rosmontis[0].Position != bossMoveDetect) { 
                //    //如果与记录坐标不相同，则迷迭香在移动中
                //    bossMoved = true;
                //}
                //bossMoveDetect = Rosmontis[0].Position;
                //如果周围有未倒下的敌人且离boss距离不远则直接进行肘击
                //if (Rosmontis[0] == null || Rosmontis[0].Downed || Rosmontis.Count < 1 || Rosmontis == null) {
                //    parent.pawn.jobs.StopAll();
                //    parent.pawn.health.RemoveHediff(parent);
                //}
                if (gapMelee == 0) { 
                    var enemiesAround = parent.pawn.Map.mapPawns.AllPawnsSpawned.Where(p =>
                        p.Position.DistanceTo(parent.pawn.Position) < 3 //距离盾卫近
                        && p.HostileTo(parent.pawn) //与自己敌对
                        && !p.Downed).ToList(); //未倒下
                    if (parent.pawn.Position.DistanceTo(Rosmontis[0].Position) < 6 //距离boss距离近
                        && enemiesAround.Count > 0 //可选敌人大于0
                        && !parent.pawn.Downed) //自己没有倒下
                    {
                        Job hitEnemy = new Job(JobDefOf.AttackMelee);
                        hitEnemy.targetA = enemiesAround[0];
                        parent.pawn.jobs.TryTakeOrderedJob(hitEnemy);
                        gapMelee = 1200;
                        return;
                    }
                }
                //获得所在第几位
                long selfAge = parent.pawn.ageTracker.AgeBiologicalTicks;
                var Shields = parent.pawn.Map.mapPawns.AllHumanlikeSpawned.Where(p => p.health.hediffSet.HasHediff(DefDatabase<HediffDef>.GetNamed("ARMIR_marchInFormation"))).ToList();
                List<long> AgeList = new List<long>();
                if (Shields.Count > 0) {
                    foreach (var shield in Shields) {
                        AgeList.Add(shield.ageTracker.AgeBiologicalTicks);
                    }
                }
                AgeList.Sort();
                int numberAge = 0;//处于第几位年龄
                if (AgeList.Count > 0) {
                    foreach (var age in AgeList) {
                        if (age == selfAge) { 
                            break;
                        }
                        numberAge++;
                    }
                }
                //设置目标坐标
                IntVec3 targetPosition = new IntVec3();
                if (numberAge <= 5)
                { //诺属于是前六位则正常定位
                    targetPosition = new IntVec3(listPosition[numberAge].x + Rosmontis[0].Position.x, listPosition[numberAge].y + Rosmontis[0].Position.y, listPosition[numberAge].z + Rosmontis[0].Position.z);
                }
                else
                { //六位之外则默认六号位置
                    targetPosition = new IntVec3(listPosition[5].x + Rosmontis[0].Position.x, listPosition[5].y + Rosmontis[0].Position.y, listPosition[5].z + Rosmontis[0].Position.z);
                }
                //诺盾卫已在目标位置上，则原地待命
                if (parent.pawn.Position == targetPosition) { 
                    Job stayC = JobMaker.MakeJob(JobDefOf.Wait_Combat);
                    stayC.expiryInterval = 3200;
                    parent.pawn.jobs.TryTakeOrderedJob(stayC);
                    hasJobGap = 0; //抵达目标位置则直接清零计时，以方便下次移动时快速反应
                }else { //盾卫不在目标位置上，给予前往目标地点的指令
                    if (hasJobGap == 0) { //遵循工作间隔
                        //目标地点可抵达则前往
                        if (targetPosition.Walkable(parent.pawn.Map)) {
                            Job toTargetPosition = JobMaker.MakeJob(JobDefOf.Goto, targetPosition);
                            parent.pawn.jobs.TryTakeOrderedJob(toTargetPosition);
                            hasJobGap = 10;
                        }else { //目标地点不可抵达则随机挑选boss周围的一格可站立位置前往
                            int searchX = -1;
                            int searchZ = 1;
                            IntVec3 newTarget = new IntVec3();
                            bool newTargetSearched = false;
                            for (int i = 0; i < 9; i++) {
                                //如果目标点位可站立且不为boss所在位置则前往
                                var newTargetPosition = new IntVec3(Rosmontis[0].Position.x + searchX, Rosmontis[0].Position.y, Rosmontis[0].Position.z + searchZ);
                                if (newTargetPosition.Walkable(parent.pawn.Map) && newTargetPosition != Rosmontis[0].Position) { 
                                    newTarget = newTargetPosition;
                                    newTargetSearched = true;
                                    break;
                                }
                                searchX++;
                                if (searchX > 2) {
                                    searchX = -1;
                                    searchZ--;
                                }
                            }
                            if (newTargetSearched) {
                                Job toTargetPosition = JobMaker.MakeJob(JobDefOf.Goto, newTarget);
                                parent.pawn.jobs.TryTakeOrderedJob(toTargetPosition);
                                hasJobGap = 10;
                            }
                        }
                    }
                }
            }
            else 
            { //地图上不存在boss迷迭香
                //直接尝试肘击附近敌人
                if (gapMelee == 0) { 
                    var enemiesAround = parent.pawn.Map.mapPawns.AllPawnsSpawned.Where(p =>
                        p.Position.DistanceTo(parent.pawn.Position) < 18 //距离盾卫近
                        && p.HostileTo(parent.pawn) //与自己敌对
                        && !p.Downed).ToList(); //未倒下
                    if (enemiesAround.Count > 0 //可选敌人大于0
                        && !parent.pawn.Downed) //自己没有倒下
                    {
                        Job hitEnemy = new Job(JobDefOf.AttackMelee);
                        hitEnemy.targetA = enemiesAround[0];
                        parent.pawn.jobs.TryTakeOrderedJob(hitEnemy);
                        gapMelee = 400;
                        return;
                    }
                }
                //通过给予短时间的原地待命清理盾卫拥有的Job
                if (gapGiveUp == 0 && gapMelee == 0) {
                    //Job stayC = JobMaker.MakeJob(JobDefOf.Wait_Combat);
                    //stayC.expiryInterval = 10;
                    //parent.pawn.jobs.TryTakeOrderedJob(stayC);
                    parent.pawn.jobs.ClearQueuedJobs();
                    parent.pawn.jobs.ClearDriver();
                    gapGiveUp = 2000;
                }
            }
        }
        private void leaveCheck() { 
            float distanceToCell = parent.pawn.Position.DistanceTo(parent.pawn.Map.Center);
            float howMuchToCell = distanceToCell / (parent.pawn.Map.Size.x / 2);
            //尚未离开过地图边缘
            if (!firstLeaveBlade) {
                //如果进入地图距离中心百分之八十以内记录为已进入地图
                if (howMuchToCell < 0.8f) { 
                    firstLeaveBlade = true;
                }
            }
            if (firstLeaveBlade) {
                //距离地图中心相当一段距离，视为即将离开地图
                if (howMuchToCell > 0.9f) {
                    //通过给予短时间的原地待命清理盾卫拥有的Job
                    Job stayC = JobMaker.MakeJob(JobDefOf.Goto,parent.pawn.Position);
                    parent.pawn.jobs.TryTakeOrderedJob(stayC);
                    //去除行军效果
                    parent.pawn.health.RemoveHediff(parent);
                }
            }
            //Log.Message("[DEBUG] 行军状态" + firstLeaveBlade);
            //Log.Message("[DEBUG] 行军距离" + distanceToCell);
            //Log.Message("[DEBUG] 行军状态" + howMuchToCell);
        }
    }
}
